use Qt containers for format/style/filter vecs.
authortsteven4 <13596209+tsteven4@users.noreply.github.com>
Thu, 21 Nov 2019 16:37:25 +0000 (09:37 -0700)
committertsteven4 <13596209+tsteven4@users.noreply.github.com>
Thu, 21 Nov 2019 16:37:25 +0000 (09:37 -0700)
defs.h
filter_vecs.cc
filterdefs.h
internal_styles.cc
mkstyle.sh
vecs.cc

diff --git a/defs.h b/defs.h
index 67ac6a90e613edfa075a95a6e85420b992377af7..ebe6149b169b43036363b214ad2ca4ae6e68e312 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -42,6 +42,7 @@
 #include <QtCore/QString>       // for QString
 #include <QtCore/QStringRef>    // for QStringRef
 #include <QtCore/QTextCodec>    // for QTextCodec
+#include <QtCore/QVector>       // for QVector
 #include <QtCore/Qt>            // for CaseInsensitive
 #include <QtCore/QtGlobal>      // for foreach
 
@@ -985,7 +986,7 @@ void setshort_is_utf8(short_handle h, int is_utf8);
 #define ARG_NOMINMAX NULL, NULL
 #define ARG_TERMINATOR {0, 0, 0, 0, 0, ARG_NOMINMAX, NULL}
 
-typedef struct arglist {
+struct arglist_t {
   const char* argstring;
   char** argval;
   const char* helpstring;
@@ -994,7 +995,7 @@ typedef struct arglist {
   const char* minvalue;                /* minimum value for numeric options */
   const char* maxvalue;                /* maximum value for numeric options */
   char* argvalptr;     /* !!! internal helper. Not used in definitions !!! */
-} arglist_t;
+};
 
 typedef enum {
   ff_type_file = 1,    /* normal format: useful to a GUI. */
@@ -1055,11 +1056,11 @@ typedef struct ff_vecs {
   const char* name;            /* dyn. initialized by find_vec */
 } ff_vecs_t;
 
-typedef struct style_vecs {
+struct style_vecs_t {
   const char* name;
   const char* style_buf;
-} style_vecs_t;
-extern style_vecs_t style_list[];
+};
+extern const QVector<style_vecs_t> style_list;
 
 [[noreturn]] void fatal(const char*, ...) PRINTFLIKE(1, 2);
 void is_fatal(int condition, const char*, ...) PRINTFLIKE(2, 3);
index c81a26de27d03432ad4edae385c98e00b4fe8a4d..00476b6d8690070c86775d4e8e905d457ebfa5f9 100644 (file)
 #include "validate.h"
 #include "gbversion.h"
 #include "inifile.h"
-#include <QtCore/QString>
-#include <cstdio>
-#include <cstdlib>
-#include <cstdlib> // qsort
 
-typedef struct {
+#include <QtCore/QList>        // for QList
+#include <QtCore/QString>      // for QString
+#include <QtCore/QStringList>  // for QStringList
+#include <QtCore/QVector>      // for QVector<>::iterator, QVector
+#include <QtCore/Qt>           // for CaseInsensitive
+
+#include <algorithm>           // for sort
+#include <cstdio>              // for printf
+#include <cstring>             // for strchr
+
+struct fl_vecs_t {
   Filter* vec;
   const char* name;
   const char* desc;
-} fl_vecs_t;
+};
 
 ArcDistanceFilter arcdist;
 BendFilter bend;
@@ -74,93 +80,93 @@ ValidateFilter validate;
 
 
 static
-fl_vecs_t filter_vec_list[] = {
+const QVector<fl_vecs_t> filter_vec_list = {
 #if FILTERS_ENABLED
-    {
-      &arcdist,
-      "arc",
-      "Include Only Points Within Distance of Arc",
-    },
-    {
-      &bend,
-      "bend",
-      "Add points before and after bends in routes"
-    },
-    {
-      &discard,
-      "discard",
-      "Remove unreliable points with high hdop or vdop"
-    },
-    {
-      &duplicate,
-      "duplicate",
-      "Remove Duplicates",
-    },
-    {
-      &interpolate,
-      "interpolate",
-      "Interpolate between trackpoints"
-    },
-    {
-      &nukedata,
-      "nuketypes",
-      "Remove all waypoints, tracks, or routes"
-    },
-    {
-      &polygon,
-      "polygon",
-      "Include Only Points Inside Polygon",
-    },
-    {
-      &position,
-      "position",
-      "Remove Points Within Distance",
-    },
-    {
-      &radius,
-      "radius",
-      "Include Only Points Within Radius",
-    },
-    {
-      &routesimple,
-      "simplify",
-      "Simplify routes",
-    },
-    {
-      &sort,
-      "sort",
-      "Rearrange waypoints, routes and/or tracks by resorting",
-    },
-    {
-      &stackfilt,
-      "stack",
-      "Save and restore waypoint lists"
-    },
-    {
-      &reverse_route,
-      "reverse",
-      "Reverse stops within routes",
-    },
-    {
-      &trackfilter,
-      "track",
-      "Manipulate track lists"
-    },
-    {
-      &transform,
-      "transform",
-      "Transform waypoints into a route, tracks into routes, ..."
-    },
-    {
-      &height,
-      "height",
-      "Manipulate altitudes"
-    },
-    {
-      &swapdata,
-      "swap",
-      "Swap latitude and longitude of all loaded points"
-    },
+  {
+    &arcdist,
+    "arc",
+    "Include Only Points Within Distance of Arc",
+  },
+  {
+    &bend,
+    "bend",
+    "Add points before and after bends in routes"
+  },
+  {
+    &discard,
+    "discard",
+    "Remove unreliable points with high hdop or vdop"
+  },
+  {
+    &duplicate,
+    "duplicate",
+    "Remove Duplicates",
+  },
+  {
+    &interpolate,
+    "interpolate",
+    "Interpolate between trackpoints"
+  },
+  {
+    &nukedata,
+    "nuketypes",
+    "Remove all waypoints, tracks, or routes"
+  },
+  {
+    &polygon,
+    "polygon",
+    "Include Only Points Inside Polygon",
+  },
+  {
+    &position,
+    "position",
+    "Remove Points Within Distance",
+  },
+  {
+    &radius,
+    "radius",
+    "Include Only Points Within Radius",
+  },
+  {
+    &routesimple,
+    "simplify",
+    "Simplify routes",
+  },
+  {
+    &sort,
+    "sort",
+    "Rearrange waypoints, routes and/or tracks by resorting",
+  },
+  {
+    &stackfilt,
+    "stack",
+    "Save and restore waypoint lists"
+  },
+  {
+    &reverse_route,
+    "reverse",
+    "Reverse stops within routes",
+  },
+  {
+    &trackfilter,
+    "track",
+    "Manipulate track lists"
+  },
+  {
+    &transform,
+    "transform",
+    "Transform waypoints into a route, tracks into routes, ..."
+  },
+  {
+    &height,
+    "height",
+    "Manipulate altitudes"
+  },
+  {
+    &swapdata,
+    "swap",
+    "Swap latitude and longitude of all loaded points"
+  },
   {
     &validate,
     "validate",
@@ -172,43 +178,33 @@ fl_vecs_t filter_vec_list[] = {
     &trackfilter,
     "track",
     "Manipulate track lists"
-  },
-#endif
-  {
-    nullptr,
-    nullptr,
-    nullptr
   }
+#endif
 };
 
 Filter*
 find_filter_vec(const char* const vecname, const char** opts)
 {
-  fl_vecs_t* vec = filter_vec_list;
-  char* v = xstrdup(vecname);
-  QString svecname = QString(v).split(",")[0];
+  const QString svecname = QString(vecname).split(',').at(0);
   int found = 0;
 
-  while (vec->vec) {
-    arglist_t* ap;
-
-    if (svecname.compare(vec->name, Qt::CaseInsensitive)) {
-      vec++;
+  for (const auto& vec : filter_vec_list) {
+    if (svecname.compare(vec.name, Qt::CaseInsensitive)) {
       continue;
     }
 
     /* step 1: initialize by inifile or default values */
-    struct arglist* args = vec->vec->get_args();
+    arglist_t* args = vec.vec->get_args();
     if (args) {
-      for (ap = args; ap->argstring; ap++) {
-        QString qtemp = inifile_readstr(global_opts.inifile, vec->name, ap->argstring);
+      for (auto ap = args; ap->argstring; ap++) {
+        QString qtemp = inifile_readstr(global_opts.inifile, vec.name, ap->argstring);
         if (qtemp.isNull()) {
           qtemp = inifile_readstr(global_opts.inifile, "Common filter settings", ap->argstring);
         }
         if (qtemp.isNull()) {
-          assign_option(vec->name, ap, ap->defaultvalue);
+          assign_option(vec.name, ap, ap->defaultvalue);
         } else {
-          assign_option(vec->name, ap, CSTR(qtemp));
+          assign_option(vec.name, ap, CSTR(qtemp));
         }
       }
     }
@@ -219,11 +215,11 @@ find_filter_vec(const char* const vecname, const char** opts)
       *opts = res+1;
 
       if (args) {
-        for (ap = args; ap->argstring; ap++) {
+        for (auto ap = args; ap->argstring; ap++) {
           char* opt = get_option(*opts, ap->argstring);
           if (opt) {
             found = 1;
-            assign_option(vec->name, ap, opt);
+            assign_option(vec.name, ap, opt);
             xfree(opt);
           }
         }
@@ -232,25 +228,23 @@ find_filter_vec(const char* const vecname, const char** opts)
       *opts = nullptr;
     }
     if (opts && opts[0] && !found) {
-      warning("'%s' is an unknown option to %s.\n", *opts, vec->name);
+      warning("'%s' is an unknown option to %s.\n", *opts, vec.name);
     }
 
     if (global_opts.debug_level >= 1) {
-      disp_vec_options(vec->name, args);
+      disp_vec_options(vec.name, args);
     }
 
-    xfree(v);
-    return vec->vec;
+    return vec.vec;
 
   }
-  xfree(v);
   return nullptr;
 }
 
 void
 free_filter_vec(Filter* filter)
 {
-  struct arglist* args = filter->get_args();
+  arglist_t* args = filter->get_args();
 
   if (args) {
     for (arglist_t* ap = args; ap->argstring; ap++) {
@@ -265,25 +259,21 @@ free_filter_vec(Filter* filter)
 void
 init_filter_vecs()
 {
-  fl_vecs_t* vec = filter_vec_list;
-  while (vec->vec) {
-    struct arglist* args = vec->vec->get_args();
+  for (const auto& vec : filter_vec_list) {
+    arglist_t* args = vec.vec->get_args();
     if (args) {
       for (arglist_t* ap = args; ap->argstring; ap++) {
         ap->argvalptr = nullptr;
       }
     }
-    vec++;
   }
 }
 
 void
 exit_filter_vecs()
 {
-  fl_vecs_t* vec = filter_vec_list;
-  while (vec->vec) {
-      (vec->vec->exit)();
-    vec++;
+  for (const auto& vec : filter_vec_list) {
+    (vec.vec->exit)();
   }
 }
 
@@ -294,10 +284,10 @@ exit_filter_vecs()
 void
 disp_filter_vecs()
 {
-  for (fl_vecs_t* vec = filter_vec_list; vec->vec; vec++) {
+  for (const auto& vec : filter_vec_list) {
     printf("   %-20.20s  %-50.50s\n",
-           vec->name, vec->desc);
-    struct arglist* args = vec->vec->get_args();
+           vec.name, vec.desc);
+    arglist_t* args = vec.vec->get_args();
     for (arglist_t* ap = args; ap && ap->argstring; ap++) {
       if (!(ap->argtype & ARGTYPE_HIDDEN))
         printf("         %-18.18s    %-.50s %s\n",
@@ -310,13 +300,13 @@ disp_filter_vecs()
 void
 disp_filter_vec(const char* vecname)
 {
-  for (fl_vecs_t* vec = filter_vec_list; vec->vec; vec++) {
-    if (case_ignore_strcmp(vec->name, vecname)) {
+  for (const auto& vec : filter_vec_list) {
+    if (case_ignore_strcmp(vec.name, vecname)) {
       continue;
     }
     printf("   %-20.20s  %-50.50s\n",
-           vec->name, vec->desc);
-    struct arglist* args = vec->vec->get_args();
+           vec.name, vec.desc);
+    arglist_t* args = vec.vec->get_args();
     for (arglist_t* ap = args; ap && ap->argstring; ap++) {
       if (!(ap->argtype & ARGTYPE_HIDDEN))
         printf("         %-18.18s    %-.50s %s\n",
@@ -326,34 +316,31 @@ disp_filter_vec(const char* vecname)
   }
 }
 
-static signed int
-alpha(const void* a, const void* b)
+static bool
+alpha(const fl_vecs_t& a, const fl_vecs_t& b)
 {
-  const fl_vecs_t* const ap = (const fl_vecs_t*) a;
-  const fl_vecs_t* const bp = (const fl_vecs_t*) b;
-
-  return case_ignore_strcmp(ap->desc, bp->desc);
+  return case_ignore_strcmp(a.desc, b.desc) < 0;
 }
 
 static
-void disp_help_url(const fl_vecs_t* vec, arglist_t* arg)
+void disp_help_url(const fl_vecs_t& vec, arglist_t* arg)
 {
-  printf("\t" WEB_DOC_DIR "/fmt_%s.html", vec->name);
+  printf("\t" WEB_DOC_DIR "/fmt_%s.html", vec.name);
   if (arg) {
-    printf("#fmt_%s_o_%s",vec->name, arg->argstring);
+    printf("#fmt_%s_o_%s",vec.name, arg->argstring);
   }
 }
 
 static void
-disp_v1(const fl_vecs_t* vec)
+disp_v1(const fl_vecs_t& vec)
 {
   disp_help_url(vec, nullptr);
   printf("\n");
-  struct arglist* args = vec->vec->get_args();
+  arglist_t* args = vec.vec->get_args();
   for (arglist_t* ap = args; ap && ap->argstring; ap++) {
     if (!(ap->argtype & ARGTYPE_HIDDEN)) {
       printf("option\t%s\t%s\t%s\t%s\t%s\t%s\t%s",
-             vec->name,
+             vec.name,
              ap->argstring,
              ap->helpstring,
              name_option(ap->argtype),
@@ -374,22 +361,17 @@ disp_v1(const fl_vecs_t* vec)
 void
 disp_filters(int version)
 {
-  fl_vecs_t* vec;
-
-  qsort(filter_vec_list,
-        sizeof(filter_vec_list) / sizeof(filter_vec_list[0]) - 1,
-        sizeof(filter_vec_list[0]),
-        alpha);
-
+  auto sorted_filter_vec_list = filter_vec_list;
+  std::sort(sorted_filter_vec_list.begin(), sorted_filter_vec_list.end(), alpha);
 
   switch (version) {
   case 0:
   case 1:
-    for (vec = filter_vec_list; vec->vec; vec++) {
+    for (const auto& vec : sorted_filter_vec_list) {
       if (version == 0) {
-        printf("%s\t%s\n", vec->name, vec->desc);
+        printf("%s\t%s\n", vec.name, vec.desc);
       } else {
-        printf("%s\t%s", vec->name, vec->desc);
+        printf("%s\t%s", vec.name, vec.desc);
         disp_v1(vec);
       }
     }
index 281c86ddf7e1821d77da95edab56d3ce178626cd..ef1f9cf1bdcc4216cce128efd987a1c788931b36 100644 (file)
@@ -44,7 +44,7 @@ typedef struct filter_vecs {
   filter_process f_process;
   filter_deinit f_deinit;
   filter_exit f_exit;
-  struct arglist* args;
+  arglist_t* args;
 } filter_vecs_t;
 
 Filter* find_filter_vec(const char* const, const char**);
index 990323463fceabfe6f2719f95317aadef1383c65..9093fe24c4e719071ba2b651879544029890ba49 100644 (file)
@@ -1,6 +1,7 @@
 /* This file is machine-generated from the contents of style/ */
 /* by mkstyle.sh.   Editing it by hand is an exceedingly bad idea. */
 
+#include <QtCore/QVector>
 #include "defs.h"
 #if CSVFMTS_ENABLED
 static char arc[] =
@@ -1489,9 +1490,7 @@ static char xmapwpt[] =
   "IFIELD      IGNORE, \"\", \"%-.31s\"\n"
   "IFIELD      DESCRIPTION, \"\", \"%-.78s\"\n"
   ;
-style_vecs_t style_list[] = {{ "xmapwpt", xmapwpt } , { "xmap2006", xmap2006 } , { "xmap", xmap } , { "tomtom_itn_places", tomtom_itn_places } , { "tomtom_itn", tomtom_itn } , { "tomtom_asc", tomtom_asc } , { "tabsep", tabsep } , { "saplus", saplus } , { "s_and_t", s_and_t } , { "ricoh", ricoh } , { "openoffice", openoffice } , { "nima", nima } , { "navigonwpt", navigonwpt } , { "mxf", mxf } , { "motoactv", motoactv } , { "mapconverter", mapconverter } , { "mainnav", mainnav } , { "land_air_sea", land_air_sea } , { "kompass_wp", kompass_wp } , { "kompass_tk", kompass_tk } , { "igoprimo_poi", igoprimo_poi } , { "igo2008_poi", igo2008_poi } , { "iblue757", iblue757 } , { "iblue747", iblue747 } , { "gpsman", gpsman } , { "gpsdrivetrack", gpsdrivetrack } , { "gpsdrive", gpsdrive } , { "geonet", geonet } , { "garmin_poi", garmin_poi } , { "garmin_g1000", garmin_g1000 } , { "garmin301", garmin301 } , { "fugawi", fugawi } , { "flysight", flysight } , { "dna", dna } , { "custom", custom } , { "cup", cup } , { "csv", csv } , { "cambridge", cambridge } , { "arc", arc } ,  {nullptr,nullptr}};
-size_t nstyles = 39;
+const QVector<style_vecs_t> style_list = {{ "xmapwpt", xmapwpt }, { "xmap2006", xmap2006 }, { "xmap", xmap }, { "tomtom_itn_places", tomtom_itn_places }, { "tomtom_itn", tomtom_itn }, { "tomtom_asc", tomtom_asc }, { "tabsep", tabsep }, { "saplus", saplus }, { "s_and_t", s_and_t }, { "ricoh", ricoh }, { "openoffice", openoffice }, { "nima", nima }, { "navigonwpt", navigonwpt }, { "mxf", mxf }, { "motoactv", motoactv }, { "mapconverter", mapconverter }, { "mainnav", mainnav }, { "land_air_sea", land_air_sea }, { "kompass_wp", kompass_wp }, { "kompass_tk", kompass_tk }, { "igoprimo_poi", igoprimo_poi }, { "igo2008_poi", igo2008_poi }, { "iblue757", iblue757 }, { "iblue747", iblue747 }, { "gpsman", gpsman }, { "gpsdrivetrack", gpsdrivetrack }, { "gpsdrive", gpsdrive }, { "geonet", geonet }, { "garmin_poi", garmin_poi }, { "garmin_g1000", garmin_g1000 }, { "garmin301", garmin301 }, { "fugawi", fugawi }, { "flysight", flysight }, { "dna", dna }, { "custom", custom }, { "cup", cup }, { "csv", csv }, { "cambridge", cambridge }, { "arc", arc }};
 #else /* CSVFMTS_ENABLED */
-style_vecs_t style_list[] = {{nullptr,nullptr}};
-size_t nstyles = 0;
+const QVector<style_vecs_t> style_list;
 #endif /* CSVFMTS_ENABLED */
index 7ce3b28fc7f5ea3fb719f408e3e50f0bdcdf2979..5ff0b50011f0c8186fe1e5af5e81b01d6d858cbc 100755 (executable)
@@ -24,24 +24,25 @@ else
        exit 1
 fi
 
+echo "#include <QtCore/QVector>"
 echo "#include \"defs.h\""
 echo "#if CSVFMTS_ENABLED"
-nstyles="0"
 for i in `dirname $0`/style/*.style
 do
        A=`basename $i | sed "s/.style$//"`
        [ $A = "README" ] && continue
        [ $A = "custom.style" ] && continue
-       ALIST="{ \"$A\", $A } , $ALIST"
+  if [ "x${ALIST}" = "x" ]; then
+         ALIST="{ \"$A\", $A }"
+  else
+         ALIST="{ \"$A\", $A }, $ALIST"
+  fi
        echo "static char $A[] ="
        $SED 's/\\/\\\\/;s/"/\\"/g;s/^\(.\)/"\1/g;s/\(.\)$/\1\\n"/g;s/^\(.\)/  \1/' $i
        echo "  ;"
-       nstyles=`expr $nstyles + 1`;
 done
-echo "style_vecs_t style_list[] = {$ALIST {nullptr,nullptr}};"
-echo "size_t nstyles = $nstyles;"
+echo "const QVector<style_vecs_t> style_list = {$ALIST};"
 echo "#else /* CSVFMTS_ENABLED */"
-echo "style_vecs_t style_list[] = {{nullptr,nullptr}};"
-echo "size_t nstyles = 0;"
+echo "const QVector<style_vecs_t> style_list;"
 echo "#endif /* CSVFMTS_ENABLED */"
 
diff --git a/vecs.cc b/vecs.cc
index 2d5d0889fb33a4e0d44e62867223d4d9152b5386..578f2326487a8890c9aa17d306f47f6dfbf36c6b 100644 (file)
--- a/vecs.cc
+++ b/vecs.cc
 
  */
 
-#include "defs.h"
-#include "csv_util.h"
-#include "gbversion.h"
-#include "inifile.h"
-#include "xcsv.h"
 #include <QtCore/QString>
-#include <cstdio>
-#include <cstdlib> // qsort
+#include <QtCore/QVector>
+
+#include <algorithm>            // for sort
+#include <cstdio>               // for printf, putchar, sscanf, size_t
+#include <cstdint>
+#include <cstring>              // for strchr, strtok, memset, strlen
+#include <ctype.h>              // for isdigit
+
+#include "defs.h"
+#include "gbversion.h"          // for WEB_DOC_DIR
+#include "inifile.h"            // for inifile_readstr
+#include "xcsv.h"               // for XcsvFile, xcsv_file, xcsv_read_internal_style, xcsv_setup_internal_style
+
 
 #define MYNAME "vecs.c"
 
-typedef struct {
+struct vecs_t {
   ff_vecs_t* vec;
   const char* name;
   QString desc;
   QString extensions; // list of possible extensions separated by '/', first is output default for GUI.
   const char* parent;
-} vecs_t;
+};
 
 extern ff_vecs_t an1_vecs;
 extern ff_vecs_t bcr_vecs;
@@ -182,7 +188,7 @@ extern ff_vecs_t f90g_track_vecs;
 extern ff_vecs_t mapfactor_vecs;
 
 static
-vecs_t vec_list[] = {
+const QVector<vecs_t> vec_list = {
 #if CSVFMTS_ENABLED
   /* XCSV must be the first entry in this table. */
   {
@@ -1085,31 +1091,22 @@ vecs_t vec_list[] = {
     "GlobalSat GH625XT GPS training watch",
     nullptr,
     nullptr,
-  },
-#endif // MAXIMAL_ENABLED
-  {
-    nullptr,
-    nullptr,
-    nullptr,
-    nullptr,
-    nullptr,
   }
+#endif // MAXIMAL_ENABLED
 };
 
 void
 init_vecs()
 {
-  vecs_t* vec = vec_list;
-  while (vec->vec) {
-    if (vec->vec->args) {
-      for (auto ap = vec->vec->args; ap->argstring; ap++) {
+  for (const auto& vec : vec_list) {
+    if (vec.vec->args) {
+      for (auto ap = vec.vec->args; ap->argstring; ap++) {
         ap->argvalptr = nullptr;
         if (ap->argval) {
           *ap->argval = nullptr;
         }
       }
     }
-    vec++;
   }
 }
 
@@ -1122,13 +1119,12 @@ is_integer(const char* c)
 void
 exit_vecs()
 {
-  vecs_t* vec = vec_list;
-  while (vec->vec) {
-    if (vec->vec->exit) {
-      (*vec->vec->exit)();
+  for (const auto& vec : vec_list) {
+    if (vec.vec->exit) {
+      (*vec.vec->exit)();
     }
-    if (vec->vec->args) {
-      for (auto ap = vec->vec->args; ap->argstring; ap++) {
+    if (vec.vec->args) {
+      for (auto ap = vec.vec->args; ap->argstring; ap++) {
         if (ap->defaultvalue &&
             (ap->argtype == ARGTYPE_INT) &&
             ! is_integer(ap->defaultvalue)) {
@@ -1140,7 +1136,6 @@ exit_vecs()
         }
       }
     }
-    vec++;
   }
 }
 
@@ -1250,8 +1245,6 @@ disp_vec_options(const char* vecname, arglist_t* ap)
 ff_vecs_t*
 find_vec(const char* vecname, const char** opts)
 {
-  vecs_t* vec = vec_list;
-  style_vecs_t* svec = style_list;
   char* v = xstrdup(vecname);
   char* svecname = strtok(v, ",");
   int found = 0;
@@ -1260,9 +1253,8 @@ find_vec(const char* vecname, const char** opts)
     fatal("A format name is required.\n");
   }
 
-  while (vec->vec) {
-    if (case_ignore_strcmp(svecname, vec->name)) {
-      vec++;
+  for (const auto& vec : vec_list) {
+    if (case_ignore_strcmp(svecname, vec.name)) {
       continue;
     }
 
@@ -1273,8 +1265,8 @@ find_vec(const char* vecname, const char** opts)
       *opts = nullptr;
     }
 
-    if (vec->vec->args) {
-      for (auto ap = vec->vec->args; ap->argstring; ap++) {
+    if (vec.vec->args) {
+      for (auto ap = vec.vec->args; ap->argstring; ap++) {
         if (res) {
           const char* opt = get_option(*opts, ap->argstring);
           if (opt) {
@@ -1284,31 +1276,31 @@ find_vec(const char* vecname, const char** opts)
             continue;
           }
         }
-        QString qopt = inifile_readstr(global_opts.inifile, vec->name, ap->argstring);
+        QString qopt = inifile_readstr(global_opts.inifile, vec.name, ap->argstring);
         if (qopt.isNull()) {
           qopt = inifile_readstr(global_opts.inifile, "Common format settings", ap->argstring);
         }
         if (qopt.isNull()) {
-          assign_option(vec->name, ap, ap->defaultvalue);
+          assign_option(vec.name, ap, ap->defaultvalue);
         } else {
-          assign_option(vec->name, ap, CSTR(qopt));
+          assign_option(vec.name, ap, CSTR(qopt));
         }
       }
     }
     if (opts && opts[0] && !found) {
-      warning("'%s' is an unknown option to %s.\n", *opts, vec->name);
+      warning("'%s' is an unknown option to %s.\n", *opts, vec.name);
     }
 
     if (global_opts.debug_level >= 1) {
-      disp_vec_options(vec->name, vec->vec->args);
+      disp_vec_options(vec.name, vec.vec->args);
     }
 
 #if CSVFMTS_ENABLED
     // xcsv_setup_internal_style( NULL );
 #endif // CSVFMTS_ENABLED
     xfree(v);
-    vec->vec->name = vec->name;        /* needed for session information */
-    return vec->vec;
+    vec.vec->name = vec.name;  /* needed for session information */
+    return vec.vec;
 
   }
 
@@ -1316,9 +1308,8 @@ find_vec(const char* vecname, const char** opts)
    * Didn't find it in the table of "real" file types, so plan B
    * is to search the list of xcsv styles.
    */
-  while (svec->name) {
-    if (case_ignore_strcmp(svecname, svec->name)) {
-      svec++;
+  for (const auto& svec : style_list) {
+    if (case_ignore_strcmp(svecname, svec.name)) {
       continue;
     }
 
@@ -1340,31 +1331,31 @@ find_vec(const char* vecname, const char** opts)
             continue;
           }
         }
-        QString qopt = inifile_readstr(global_opts.inifile, svec->name, ap->argstring);
+        QString qopt = inifile_readstr(global_opts.inifile, svec.name, ap->argstring);
         if (qopt.isNull()) {
           qopt = inifile_readstr(global_opts.inifile, "Common format settings", ap->argstring);
         }
         if (qopt.isNull()) {
-          assign_option(svec->name, ap, ap->defaultvalue);
+          assign_option(svec.name, ap, ap->defaultvalue);
         } else {
-          assign_option(svec->name, ap, CSTR(qopt));
+          assign_option(svec.name, ap, CSTR(qopt));
         }
       }
     }
 
     if (opts && opts[0] && !found) {
-      warning("'%s' is an unknown option to %s.\n", *opts, svec->name);
+      warning("'%s' is an unknown option to %s.\n", *opts, svec.name);
     }
 
     if (global_opts.debug_level >= 1) {
-      disp_vec_options(svec->name, vec_list[0].vec->args);
+      disp_vec_options(svec.name, vec_list[0].vec->args);
     }
 #if CSVFMTS_ENABLED
-    xcsv_setup_internal_style(svec->style_buf);
+    xcsv_setup_internal_style(svec.style_buf);
 #endif // CSVFMTS_ENABLED
 
     xfree(v);
-    vec_list[0].vec->name = svec->name;        /* needed for session information */
+    vec_list[0].vec->name = svec.name; /* needed for session information */
     return vec_list[0].vec;
   }
 
@@ -1424,14 +1415,10 @@ get_option(const char* iarglist, const char* argname)
  *  Display the available formats in a format that's easy for humans to
  *  parse for help on available command line options.
  */
-static signed int
-alpha(const void* a, const void* b)
+static bool
+alpha(const vecs_t& a, const vecs_t& b)
 {
-
-  const vecs_t* const* ap = (const vecs_t *const*) a;
-  const vecs_t* const* bp = (const vecs_t *const*) b;
-
-  return case_ignore_strcmp((*ap)->desc , (*bp)->desc);
+  return case_ignore_strcmp(a.desc, b.desc) < 0;
 }
 
 /*
@@ -1439,79 +1426,63 @@ alpha(const void* a, const void* b)
  * alphabetically.  Returns an allocated copy of a style_vecs_array
  * that's populated and sorted.
  */
-vecs_t**
-sort_and_unify_vecs(int* ctp)
+QVector<vecs_t>
+sort_and_unify_vecs()
 {
-  size_t vc;
-  vecs_t** svp;
-#if CSVFMTS_ENABLED
-#endif
-  int i = 0;
-
-  /* Get a count from both the vec (normal) and the svec (csv) lists */
-
-#if CSVFMTS_ENABLED
-  extern size_t nstyles;
-  vc = sizeof vec_list / sizeof vec_list[0] - 1 + nstyles;
-#else
-  vc = sizeof vec_list / sizeof vec_list[0] - 1;
-#endif // CSVFMTS_ENABLED
-
-
-  svp = (vecs_t**)xcalloc(vc, sizeof(style_vecs_t*));
+  QVector<vecs_t> svp;
+  svp.reserve(vec_list.size() + style_list.size());
   /* Normal vecs are easy; populate the first part of the array. */
-  for (vecs_t* vec = vec_list; vec->vec; vec++, i++) {
-    svp[i] = vec;
-    if (svp[i]->parent == nullptr) {
-      svp[i]->parent = svp[i]->name;
+  for (const auto& vec : vec_list) {
+    vecs_t uvec = vec;
+    if (uvec.parent == nullptr) {
+      uvec.parent = uvec.name;
     }
+    svp.append(uvec);
   }
 
-#if CSVFMTS_ENABLED
   /* Walk the style list, parse the entries, dummy up a "normal" vec */
-  for (style_vecs_t* svec = style_list; svec->name; svec++, i++)  {
-    xcsv_read_internal_style(svec->style_buf);
-    svp[i] = new vecs_t;
-    svp[i]->name = svec->name;
-    svp[i]->vec = (ff_vecs_t*) xmalloc(sizeof(*svp[i]->vec));
-    svp[i]->extensions = xcsv_file.extension;
-    *svp[i]->vec = *vec_list[0].vec; /* Inherits xcsv opts */
+  for (const auto& svec : style_list) {
+    xcsv_read_internal_style(svec.style_buf);
+    vecs_t uvec;
+    uvec.name = svec.name;
+    uvec.vec = new ff_vecs_t; /* LEAK */
+    uvec.extensions = xcsv_file.extension;
+    *uvec.vec = *vec_list[0].vec; /* Inherits xcsv opts */
     /* Reset file type to inherit ff_type from xcsv for everything
      * except the xcsv format itself, which we leave as "internal"
      */
-    if (case_ignore_strcmp(svec->name, "xcsv")) {
-      svp[i]->vec->type = xcsv_file.type;
+    if (case_ignore_strcmp(svec.name, "xcsv")) {
+      uvec.vec->type = xcsv_file.type;
       /* Skip over the first help entry for all but the
        * actual 'xcsv' format - so we don't expose the
        * 'full path to xcsv style file' argument to any
        * GUIs for an internal format.
        */
-      svp[i]->vec->args++;
+      uvec.vec->args++;
     }
-    memset(&svp[i]->vec->cap, 0, sizeof(svp[i]->vec->cap));
+    memset(&uvec.vec->cap, 0, sizeof(uvec.vec->cap));
     switch (xcsv_file.datatype) {
     case unknown_gpsdata:
     case wptdata:
-      svp[i]->vec->cap[ff_cap_rw_wpt] = (ff_cap)(ff_cap_read | ff_cap_write);
+      uvec.vec->cap[ff_cap_rw_wpt] = (ff_cap)(ff_cap_read | ff_cap_write);
       break;
     case trkdata:
-      svp[i]->vec->cap[ff_cap_rw_trk] = (ff_cap)(ff_cap_read | ff_cap_write);
+      uvec.vec->cap[ff_cap_rw_trk] = (ff_cap)(ff_cap_read | ff_cap_write);
       break;
     case rtedata:
-      svp[i]->vec->cap[ff_cap_rw_rte] = (ff_cap)(ff_cap_read | ff_cap_write);
+      uvec.vec->cap[ff_cap_rw_rte] = (ff_cap)(ff_cap_read | ff_cap_write);
       break;
     default:
       ;
     }
-    svp[i]->desc = xcsv_file.description;
-    svp[i]->parent = "xcsv";
+    uvec.desc = xcsv_file.description;
+    uvec.parent = "xcsv";
+    svp.append(uvec);
   }
-#endif // CSVFMTS_ENABLED
 
   /* Now that we have everything in an array, alphabetize them */
-  qsort(svp, vc, sizeof(*svp), alpha);
+  std::sort(svp.begin(), svp.end(), alpha);
 
-  *ctp = i;
   return svp;
 }
 
@@ -1520,15 +1491,13 @@ sort_and_unify_vecs(int* ctp)
 void
 disp_vecs()
 {
-  int vc;
-
-  vecs_t** svp = sort_and_unify_vecs(&vc);
-  for (int i = 0; i<vc; i++) {
-    if (svp[i]->vec->type == ff_type_internal)  {
+  const auto svp = sort_and_unify_vecs();
+  for (const auto& vec : svp) {
+    if (vec.vec->type == ff_type_internal)  {
       continue;
     }
-    printf(VEC_FMT, svp[i]->name, CSTR(svp[i]->desc));
-    for (auto ap = svp[i]->vec->args; ap && ap->argstring; ap++) {
+    printf(VEC_FMT, vec.name, CSTR(vec.desc));
+    for (auto ap = vec.vec->args; ap && ap->argstring; ap++) {
       if (!(ap->argtype & ARGTYPE_HIDDEN))
         printf("         %-18.18s    %s%-.50s %s\n",
                ap->argstring,
@@ -1538,22 +1507,19 @@ disp_vecs()
                (ap->argtype & ARGTYPE_REQUIRED)?"(required)":"");
     }
   }
-  xfree(svp);
 }
 
 void
 disp_vec(const char* vecname)
 {
-  int vc;
-
-  vecs_t** svp = sort_and_unify_vecs(&vc);
-  for (int i = 0; i<vc; i++) {
-    if (case_ignore_strcmp(svp[i]->name, vecname))  {
+  const auto svp = sort_and_unify_vecs();
+  for (const auto& vec : svp) {
+    if (case_ignore_strcmp(vec.name, vecname))  {
       continue;
     }
 
-    printf(VEC_FMT, svp[i]->name, CSTR(svp[i]->desc));
-    for (auto ap = svp[i]->vec->args; ap && ap->argstring; ap++) {
+    printf(VEC_FMT, vec.name, CSTR(vec.desc));
+    for (auto ap = vec.vec->args; ap && ap->argstring; ap++) {
       if (!(ap->argtype & ARGTYPE_HIDDEN))
         printf("         %-18.18s    %s%-.50s %s\n",
                ap->argstring,
@@ -1563,7 +1529,6 @@ disp_vec(const char* vecname)
                (ap->argtype & ARGTYPE_REQUIRED)?"(required)":"");
     }
   }
-  xfree(svp);
 }
 
 /*
@@ -1595,7 +1560,7 @@ disp_v1(ff_type t)
 static void
 disp_v2(ff_vecs_t* v)
 {
-  for (auto &i : v->cap) {
+  for (autoi : v->cap) {
     putchar((i & ff_cap_read) ? 'r' : '-');
     putchar((i & ff_cap_write) ? 'w' : '-');
   }
@@ -1622,24 +1587,24 @@ name_option(uint32_t type)
 }
 
 static
-void disp_help_url(const vecs_t* vec, arglist_t* arg)
+void disp_help_url(const vecs_t& vec, arglist_t* arg)
 {
-  printf("\t" WEB_DOC_DIR "/fmt_%s.html", vec->name);
+  printf("\t" WEB_DOC_DIR "/fmt_%s.html", vec.name);
   if (arg) {
-    printf("#fmt_%s_o_%s",vec->name, arg->argstring);
+    printf("#fmt_%s_o_%s",vec.name, arg->argstring);
   }
   printf("\n");
 }
 
 
 static void
-disp_v3(const vecs_t* vec)
+disp_v3(const vecs_t& vec)
 {
   disp_help_url(vec, nullptr);
-  for (auto ap = vec->vec->args; ap && ap->argstring; ap++) {
+  for (auto ap = vec.vec->args; ap && ap->argstring; ap++) {
     if (!(ap->argtype & ARGTYPE_HIDDEN)) {
       printf("option\t%s\t%s\t%s\t%s\t%s\t%s\t%s",
-             vec->name,
+             vec.name,
              ap->argstring,
              ap->helpstring,
              name_option(ap->argtype),
@@ -1660,115 +1625,109 @@ disp_v3(const vecs_t* vec)
 void
 disp_formats(int version)
 {
-  vecs_t** svp;
-  vecs_t* vec;
-  int vc = 0;
+  const auto svp = sort_and_unify_vecs();
   switch (version) {
-    case 0:
-    case 1:
-    case 2:
-    case 3:
-    svp = sort_and_unify_vecs(&vc);
-    for (int i = 0; i<vc; i++,vec++) {
-      vec = svp[i];
-
+  case 0:
+  case 1:
+  case 2:
+  case 3:
+    for (const auto& vec : svp) {
       /* Version 1 displays type at front of all types.
        * Version 0 skips internal types.
        */
       if (version > 0) {
-        disp_v1(vec->vec->type);
+        disp_v1(vec.vec->type);
       } else {
-        if (vec->vec->type == ff_type_internal) {
+        if (vec.vec->type == ff_type_internal) {
           continue;
         }
       }
       if (version >= 2) {
-        disp_v2(vec->vec);
+        disp_v2(vec.vec);
       }
-      printf("%s\t%s\t%s%s%s\n", vec->name,
-        !vec->extensions.isEmpty() ? CSTR(vec->extensions) : "",
-        CSTR(vec->desc),
-        version >= 3 ? "\t" : "",
-        version >= 3 ? vec->parent : "");
+      printf("%s\t%s\t%s%s%s\n", vec.name,
+             !vec.extensions.isEmpty() ? CSTR(vec.extensions) : "",
+             CSTR(vec.desc),
+             version >= 3 ? "\t" : "",
+             version >= 3 ? vec.parent : "");
       if (version >= 3) {
         disp_v3(vec);
       }
     }
-    xfree(svp);
     break;
-    default:
+  default:
     ;
   }
 }
 
 static bool
-validate_vec(const vecs_t* vec)
+validate_vec(const vecs_t& vec)
 {
   bool ok = true;
 
-  if (!((vec->vec->cap[0]|vec->vec->cap[1]|vec->vec->cap[2]) & ff_cap_write)) {
-    if (vec->vec->wr_init != nullptr) {
-      printf("ERROR no write capability but non-null wr_init %s\n", vec->name);
+  if (!((vec.vec->cap[0]|vec.vec->cap[1]|vec.vec->cap[2]) & ff_cap_write)) {
+    if (vec.vec->wr_init != nullptr) {
+      printf("ERROR no write capability but non-null wr_init %s\n", vec.name);
       ok = false;
     }
   }
-  if (!((vec->vec->cap[0]|vec->vec->cap[1]|vec->vec->cap[2]) & ff_cap_read)) {
-    if (vec->vec->rd_init != nullptr) {
-      printf("ERROR no read capbility but non-null rd_init %s\n", vec->name);
+  if (!((vec.vec->cap[0]|vec.vec->cap[1]|vec.vec->cap[2]) & ff_cap_read)) {
+    if (vec.vec->rd_init != nullptr) {
+      printf("ERROR no read capbility but non-null rd_init %s\n", vec.name);
       ok = false;
     }
   }
-  if ((vec->vec->cap[0]|vec->vec->cap[1]|vec->vec->cap[2]) & ff_cap_write) {
-    if (vec->vec->wr_init == nullptr) {
-      printf("ERROR write capability but null wr_init %s\n", vec->name);
+  if ((vec.vec->cap[0]|vec.vec->cap[1]|vec.vec->cap[2]) & ff_cap_write) {
+    if (vec.vec->wr_init == nullptr) {
+      printf("ERROR write capability but null wr_init %s\n", vec.name);
       ok = false;
     }
   }
-  if ((vec->vec->cap[0]|vec->vec->cap[1]|vec->vec->cap[2]) & ff_cap_read) {
-    if (vec->vec->rd_init == nullptr) {
-      printf("ERROR read capability but null rd_init %s\n", vec->name);
+  if ((vec.vec->cap[0]|vec.vec->cap[1]|vec.vec->cap[2]) & ff_cap_read) {
+    if (vec.vec->rd_init == nullptr) {
+      printf("ERROR read capability but null rd_init %s\n", vec.name);
       ok = false;
     }
   }
 
-  if (vec->vec->wr_init != nullptr) {
-    if (vec->vec->write == nullptr) {
-      printf("ERROR nonnull wr_init but null write %s\n", vec->name);
+  if (vec.vec->wr_init != nullptr) {
+    if (vec.vec->write == nullptr) {
+      printf("ERROR nonnull wr_init but null write %s\n", vec.name);
       ok = false;
     }
-    if (vec->vec->wr_deinit == nullptr) {
-      printf("ERROR nonnull wr_init but null wr_deinit %s\n", vec->name);
+    if (vec.vec->wr_deinit == nullptr) {
+      printf("ERROR nonnull wr_init but null wr_deinit %s\n", vec.name);
       ok = false;
     }
   }
-  if (vec->vec->wr_init == nullptr) {
-    if (vec->vec->write != nullptr) {
-      printf("ERROR null wr_init with non-null write %s\n", vec->name);
+  if (vec.vec->wr_init == nullptr) {
+    if (vec.vec->write != nullptr) {
+      printf("ERROR null wr_init with non-null write %s\n", vec.name);
       ok = false;
     }
-    if (vec->vec->wr_deinit != nullptr) {
-      printf("ERROR null wr_init with non-null wr_deinit %s\n", vec->name);
+    if (vec.vec->wr_deinit != nullptr) {
+      printf("ERROR null wr_init with non-null wr_deinit %s\n", vec.name);
       ok = false;
     }
   }
 
-  if (vec->vec->rd_init != nullptr) {
-    if (vec->vec->read == nullptr) {
-      printf("ERROR nonnull rd_init but null read %s\n", vec->name);
+  if (vec.vec->rd_init != nullptr) {
+    if (vec.vec->read == nullptr) {
+      printf("ERROR nonnull rd_init but null read %s\n", vec.name);
       ok = false;
     }
-    if (vec->vec->rd_deinit == nullptr) {
-      printf("ERROR nonnull rd_init but null rd_deinit %s\n", vec->name);
+    if (vec.vec->rd_deinit == nullptr) {
+      printf("ERROR nonnull rd_init but null rd_deinit %s\n", vec.name);
       ok = false;
     }
   }
-  if (vec->vec->rd_init == nullptr) {
-    if (vec->vec->read != nullptr) {
-      printf("ERROR null rd_init with non-null read %s\n", vec->name);
+  if (vec.vec->rd_init == nullptr) {
+    if (vec.vec->read != nullptr) {
+      printf("ERROR null rd_init with non-null read %s\n", vec.name);
       ok = false;
     }
-    if (vec->vec->rd_deinit != nullptr) {
-      printf("ERROR null rd_init with non-null rd_deinit %s\n", vec->name);
+    if (vec.vec->rd_deinit != nullptr) {
+      printf("ERROR null rd_init with non-null rd_deinit %s\n", vec.name);
       ok = false;
     }
   }
@@ -1780,10 +1739,8 @@ int validate_formats()
 {
   bool ok = true;
 
-  const vecs_t* vec = vec_list;
-  while (vec->vec) {
+  for (const auto& vec : vec_list) {
     ok = validate_vec(vec) && ok;
-    vec++;
   }
 
   return ok? 0 : 1;